package no.ntnu.item.ttm4115.termproject.classmanager;

import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import java.util.Map.Entry;

import no.ntnu.item.ttm4115.termproject.AddGroupFromGUI;
import no.ntnu.item.ttm4115.termproject.CreateNewPlayerFromGUI;
import no.ntnu.item.ttm4115.termproject.DeleteGroupFromGUI;
import no.ntnu.item.ttm4115.termproject.DeletePlayerFromGUI;
import no.ntnu.item.ttm4115.termproject.PlayerAddedGroup;
import no.ntnu.item.ttm4115.termproject.PrepareNewGroupToCM;
import no.ntnu.item.ttm4115.termproject.RegisterGA;
import no.ntnu.item.ttm4115.termproject.RegisterPA;
import no.ntnu.item.ttm4115.termproject.RegisterPlayer;
import no.ntnu.item.ttm4115.termproject.RegisterTeacherAgent;
import no.ntnu.item.ttm4115.termproject.ReturnPlayersForGroupCreation;
import no.ntnu.item.ttm4115.termproject.SendConfigToTeacher;
import no.ntnu.item.ttm4115.termproject.SendConfigToTeacherPlayer;
import no.ntnu.item.ttm4115.termproject.SendRoleRequestToNewGroup;
import no.ntnu.item.ttm4115.termproject.SetOnlinePlayers;
import no.ntnu.item.ttm4115.termproject.UpdateGroupFromGUI;
import no.ntnu.item.ttm4115.termproject.UpdatePlayerNewStatusToAll;
import no.ntnu.item.ttm4115.termproject.UpdatePlayerSettingsFromGUI;
import no.ntnu.item.ttm4115.termproject.UpdateStatusToPlayers;
import no.ntnu.item.ttm4115.termproject.UserLogin;
import no.ntnu.item.ttm4115.termproject.extrasagent.Group;
import no.ntnu.item.ttm4115.termproject.extrasagent.Player;
import no.tellu.common.javaframe.messages.RoleRequestMsg;

import com.thoughtworks.xstream.XStream;
import no.ntnu.item.ttm4115.termproject.Alternative;
import no.ntnu.item.ttm4115.termproject.SocialPlayerSig;




public class ClassManagerActions extends Object {

	public static void initialize(ClassManagerSM asm){
	    // TODO edit action statements
		
		for(Group ga:asm.configuration.getGroups()){
			System.out.println("Requesting to create GA");
			asm.sendMessage(new RoleRequestMsg(ga.getGroupName(),"GroupAgent"),asm.getMyActorAddress());
			Vector<Player> plrs = ga.getPlayers();
			System.out.println("Total players: "+ plrs.size());
			//for(Player pa:plrs){
			//	System.out.println("Requesting to create PA");
				//asm.sendMessage(new RoleRequestMsg(pa.getUserName(),"PlayerAgent"),asm.getMyActorAddress());
			//}
		}
	}

	public static void registerGA(RegisterGA signal, ClassManagerSM asm){
		System.out.println("Class Manager receives the register GA signal and updating groups");
		asm.configuration.updateGroup(signal.actorAddress);
	}

	public static void registerPA(RegisterPA signal, ClassManagerSM asm){
	   	System.out.println("Class Manager receives the register PA signal and updating players");
		asm.configuration.updatePlayer(signal.actorAddress);
	}

	public static void addNewPlayer(CreateNewPlayerFromGUI signal, ClassManagerSM asm){

		XStream xstream = new XStream();
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object object = (Object)xstream.fromXML(signal.xmlPlayer);
		Player player = (Player)object;
		
		asm.configuration.addPlayerToGame(player);

	}


	public static void updatePlayerSettings(UpdatePlayerSettingsFromGUI signal, ClassManagerSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object object = (Object)xstream.fromXML(signal.xmlPlayer);
		Player player = (Player)object;
		
		 
		asm.configuration.updatePlayerSettings(player,signal.oldUserName);
	}


	public static void deletePlayer(DeletePlayerFromGUI signal, ClassManagerSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		Object object = xstream.fromXML(signal.xmlPlayer);
		Player player = (Player)object;
		asm.configuration.deletePlayer(player);
	}

	public static void addGroup(AddGroupFromGUI signal, ClassManagerSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Group().getClass().getClassLoader());
		//xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("group", Group.class);
		xstream.alias("player",Player.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		Object object = xstream.fromXML(signal.xmlGroup);
		Group group = (Group)object;
	    asm.configuration.addGroupToGame(group);
	}


	public static void userLoggingIn(UserLogin signal, ClassManagerSM asm){
		asm.playerAddress = signal.getSenderRole();
		asm.configuration.userLogin(signal, asm.playerAddress);
		    
	
	}

	public static void hashOnlinePlayer(RegisterPlayer signal, ClassManagerSM asm){
	    // TODO edit action statements
			XStream xstream = new XStream();
			xstream.setClassLoader(new Player().getClass().getClassLoader());
			xstream.alias("player", Player.class);
			xstream.alias("group", Group.class);
			xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
			
			Object object = (Object)xstream.fromXML(signal.playerXML);
			Player player = (Player)object;
			
			player.setActorAddress(signal.getSenderRole());
			player.setStatus("Online");
			player.setLocation("NTNU");
	
	
			
			 if(!asm.onlinePlayersMap.containsKey(player.getUserName())) {
				 asm.onlinePlayersMap.put(player.getUserName(), player);	
			 }
			
		    Iterator<Entry<String, Player>> iterator = asm.onlinePlayersMap.entrySet().iterator();
			
		    while(iterator.hasNext()){
				Map.Entry<String, Player> me = (Map.Entry<String, Player>)iterator.next();
				
				 Iterator<Entry<String, Player>> iterator2 = asm.onlinePlayersMap.entrySet().iterator();	
					while(iterator2.hasNext()){
						Map.Entry<String, Player> me2 = (Map.Entry<String, Player>)iterator2.next();
						
						Player sendPlayer = new Player(me2.getValue().getUserName(), me2.getValue().getLocation(), me2.getValue().getStatus(), me2.getValue().getActorAddress());
						String xmlOnlinePlayersMap = xstream.toXML(sendPlayer);
						

						asm.sendMessage(new SetOnlinePlayers(xmlOnlinePlayersMap), me.getValue().getActorAddress());
					}
				
			}
	}

	public static void uploadConfiguration(RegisterTeacherAgent signal, ClassManagerSM asm){
	    	XStream xstream = new XStream();
			xstream.setClassLoader(new Player().getClass().getClassLoader());
			xstream.alias("player", Player.class);
			xstream.alias("group", Group.class);
			xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
			boolean groupVector = false;
			boolean playerVector = false;
			for (int i = 0; i < asm.configuration.getGroups().size(); i++) {
				String group = xstream.toXML(asm.configuration.getGroups().elementAt(i));
				if(i == (asm.configuration.getGroups().size()-1)){
					groupVector = true;
					System.out.println("Her er groupVector blitt TRUE!!!");
				}
				asm.sendMessage(new SendConfigToTeacher(group,groupVector), signal.getSenderRole());
			}
			
			for (int i = 0; i < asm.configuration.getPlayers().size(); i++) {
				String player = xstream.toXML(asm.configuration.getPlayers().elementAt(i));
				if(i == (asm.configuration.getPlayers().size()-1)){
					playerVector = true;
					System.out.println("Her er playerVector satt til TRUE!!!!");
				}
				asm.sendMessage(new SendConfigToTeacherPlayer(player,playerVector), signal.getSenderRole());
			}
	
	}

	public static void updateNewPlayerStatus(UpdatePlayerNewStatusToAll signal, ClassManagerSM asm){
	    XStream xstream = new XStream();
			xstream.setClassLoader(new Player().getClass().getClassLoader());
			xstream.alias("player", Player.class);
			xstream.alias("group", Group.class);
			xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
			
			Object object = (Object)xstream.fromXML(signal.statusChangePlayer);
			Player player = (Player)object;
			
			Iterator<Entry<String, Player>> iterator3 = asm.onlinePlayersMap.entrySet().iterator();
			
			while(iterator3.hasNext()){
				Map.Entry<String, Player> me3 = (Map.Entry<String, Player>)iterator3.next();
				if(me3.getKey().equals(player.getUserName())){
					me3.getValue().setStatus(player.getStatus());
					player = me3.getValue();
				}
			}
			
			Iterator<Entry<String, Player>> iterator4 = asm.onlinePlayersMap.entrySet().iterator();
			
			Player sendPlayer = new Player(player.getUserName(), player.getLocation(), player.getStatus(), player.getActorAddress());
			String xmlPlayer= xstream.toXML(sendPlayer);
			
			while(iterator4.hasNext()){
				Map.Entry<String, Player> me4 = (Map.Entry<String, Player>)iterator4.next();
				
				asm.sendMessage(new UpdateStatusToPlayers(xmlPlayer), me4.getValue().getActorAddress());
				
			}
			
	
	}

	public static void FetchPlayers(PrepareNewGroupToCM signal, ClassManagerSM asm){
		
    	XStream xstream = new XStream();
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		boolean playerFinished = false;
		
		Iterator<Entry<String, Player>> iterator = asm.onlinePlayersMap.entrySet().iterator();
		
		System.out.println("CA received something from: " +signal.getSenderRole());
		while(iterator.hasNext()){
			Map.Entry<String, Player> me = (Map.Entry<String, Player>)iterator.next();
			
			String xmlPlayer= xstream.toXML(me.getValue());
			
			if(!iterator.hasNext()){
				playerFinished = true;
			}
			asm.sendMessage(new ReturnPlayersForGroupCreation(xmlPlayer, playerFinished), signal.getSenderRole());	
		}
		
		
	}

	public static void addGroupByPlayer(PlayerAddedGroup signal, ClassManagerSM asm){
	    XStream xstream = new XStream();
		xstream.setClassLoader(new Group().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		Object object = xstream.fromXML(signal.xmlGroup);
		Object object2 = xstream.fromXML(signal.xmlPlayer);
		Group group = (Group)object;
		Player player = (Player) object2;
			
		asm.configuration.addGroupToGame(group);
		player.addGroup(group);
		asm.configuration.updatePlayerSettings(player);
		    
		String xmlPlayer = xstream.toXML(player);
		asm.sendMessage(new SendRoleRequestToNewGroup(xmlPlayer, group.getGroupName()), signal.getSenderRole());
	}

	public static void updateGroup(UpdateGroupFromGUI signal, ClassManagerSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Group().getClass().getClassLoader());
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("group", Group.class);
		xstream.alias("player",Player.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object object = xstream.fromXML(signal.xmlGroup);
		Group group = (Group)object;
		
		asm.configuration.updateGroupSettings(group,signal.oldGroupName);
	}

	public static void deleteGroup(DeleteGroupFromGUI signal, ClassManagerSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Group().getClass().getClassLoader());
		xstream.setClassLoader(new Player().getClass().getClassLoader());
		xstream.alias("group", Group.class);
		xstream.alias("player",Player.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object object = xstream.fromXML(signal.xmlGroup);
		Group group = (Group)object;
		
		asm.configuration.deleteGroup(group);
	}

	public static void saion(SocialPlayerSig signal, ClassManagerSM asm){
		XStream xstream = new XStream();
		xstream.setClassLoader(new Group().getClass().getClassLoader());
		xstream.alias("player", Player.class);
		xstream.alias("group", Group.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		Object object = xstream.fromXML(signal.xmlPlayer);
	
		Player player = (Player) object;
		Group group = player.getGroups().get(player.getGroups().size()-1);
		asm.configuration.addGroupToGame(group);
		//player.addGroup(group);
		asm.configuration.updatePlayerSettings(player);
		    
		String xmlPlayer = xstream.toXML(player);
		asm.sendMessage(new SendRoleRequestToNewGroup(xmlPlayer, group.getGroupName()), signal.getSenderRole());
	}


}
